package com.qigao.mall.web.controller.notify;

import com.qigao.mall.api.ChannelRouteService;
import com.qigao.mall.api.PayService;
import com.qigao.mall.commons.dto.PayNotifyDto;
import com.qigao.mall.commons.enums.PayStatusEnum;
import com.qigao.mall.commons.enums.ResultCode;
import com.qigao.mall.commons.enums.WebSourceEnum;
import com.qigao.mall.commons.exceptions.BusinessException;
import com.qigao.mall.commons.utils.DateUtil;
import com.qigao.mall.web.utils.RequestUtils;
import io.swagger.annotations.Api;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Map;

/**
 * @author luiz
 * @Title: com.qigao.mall.web.controller.app
 * @ProjectName three-mall
 * @date 2019-11-2019/11/11 16:30
 * @Description:
 */
@RestController
@RequestMapping("/qigao/aliPayNotify/")
@Api(tags = "支付宝通知接口",value = "支付宝通知接口")
public class AliPayNotifyController {
    private static final Logger logger= LoggerFactory.getLogger(AliPayNotifyController.class);
    @Resource
    private PayService payService;
    @Resource
    ChannelRouteService channelRouteService;

    /**
     * 支付宝付款通知入口
     */
    @PostMapping("pay")
    public String payNotify(HttpServletRequest request){
        Map respMap=RequestUtils.getParameterMap(request);
        logger.info("[支付宝付款通知]接受到的参数:{}",respMap);
        String retMsg="SUCCESS";
        try{
            //签名校验
        /*    String signValue=(String) respMap.get("sign");
            respMap.remove("sign");
            respMap.remove("sign_type");
            // todo 按照支付渠道校验签名
            String webSource= WebSourceEnum.H5_WEB.getCode();
            String payWay= PayProductEnum.ALIPAY_WAP_WEB.getProductCode();
            TbMerChannel tbMerChannel=tbMerChannelMapper.selectByIndex(qiGaoProperties.getMerNo(),webSource,payWay);
            String respStr=PairString.createLinkString(respMap);
            boolean verifyFlag= RSAUtils.verifyWithRsa2(respStr,signValue,tbMerChannel.getPubKey());*/
            boolean verifyFlag=channelRouteService.verifySign(respMap,WebSourceEnum.H5_WEB.getCode());
            if(!verifyFlag){
                logger.warn("【支付宝付款通知】报文校验失败!{}",verifyFlag);
                throw new BusinessException(ResultCode.SIGN_VALID_ERROR);
            }
            PayNotifyDto payNotifyDto=buildRespDto(respMap);
            if(PayStatusEnum.PAY_INIT.equals(payNotifyDto.getTradeStatus())){
                logger.warn("【支付宝付款通知】支付处理中订单无需处理....");
                throw new BusinessException(ResultCode.CHANNEL_ERROR);
            }
            payService.processNotifyOrder(payNotifyDto);
            logger.info("[支付宝付款通知]处理成功!");
        }catch (BusinessException be){
            retMsg="FAIL";
            logger.error("[支付宝付款通知]处理发生业务异常:{}",be);
        }catch (Exception e){
            retMsg="FAIL";
            logger.error("[支付宝付款通知]处理发生异常:{}",e);
        }
        return retMsg;
    }

    private PayNotifyDto buildRespDto(Map respMap) {
        PayNotifyDto payNotifyDto=new PayNotifyDto();
        payNotifyDto.setAppId((String) respMap.get("app_id"));
        payNotifyDto.setMchId((String) respMap.get("mch_id"));
        payNotifyDto.setNonceStr((String) respMap.get("nonce_str"));
        payNotifyDto.setOpenid((String) respMap.get("buyer_logon_id"));
        payNotifyDto.setBuylerId((String) respMap.get("buyer_id"));
        String totalFee=(String) respMap.get("total_amount");
        if(!StringUtils.isEmpty(totalFee)){
            payNotifyDto.setTotalFee(new BigDecimal(totalFee));
        }
        String tradeStatus=(String)respMap.get("trade_status");
        if("WAIT_BUYER_PAY".equals(tradeStatus)){
            payNotifyDto.setTradeStatus(PayStatusEnum.PAY_INIT);
        } else if("TRADE_CLOSED".equals(tradeStatus)){
            payNotifyDto.setTradeStatus(PayStatusEnum.PAY_CLOSE);
        }else if("TRADE_SUCCESS".equals(tradeStatus)){
            payNotifyDto.setTradeStatus(PayStatusEnum.PAY_SUCCESS);
        }else if("TRADE_FINISHED".equals(tradeStatus)){
            payNotifyDto.setTradeStatus(PayStatusEnum.PAY_FINISH);
        }
        payNotifyDto.setTransactionId((String) respMap.get("trade_no"));
        payNotifyDto.setOutTradeNo((String) respMap.get("out_trade_no"));
        String payTimeStr=(String) respMap.get("gmt_payment");
        if(!StringUtils.isEmpty(payTimeStr)){
            payNotifyDto.setPaySuccessTime(DateUtil.pareDate(payTimeStr,"yyyy-MM-dd HH:mm:ss"));
        }
        String closeTimeStr=(String) respMap.get("gmt_close");
        if(!StringUtils.isEmpty(closeTimeStr)){
            payNotifyDto.setCloseTime(DateUtil.pareDate(closeTimeStr,"yyyy-MM-dd HH:mm:ss"));
        }
        return payNotifyDto;
    }


}
